
package com.auxgroup.hr.front.site.co;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.auxgroup.hr.front.commons.exception.VailidationMsg;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.auxgroup.hr.front.commons.BaseRetCode;
import com.auxgroup.hr.front.commons.Constant;
import com.auxgroup.hr.front.commons.exception.FrontException;
import com.auxgroup.hr.front.commons.exception.VailidationMsg;
import com.auxgroup.hr.front.commons.exception.ValidationException;
import com.auxgroup.hr.front.commons.utils.Bean2MapUtils;
import com.auxgroup.hr.front.commons.utils.Underline2Camel;
import com.auxgroup.hr.front.commons.vo.BaseResponseVO;
import com.auxgroup.hr.front.dao.domain.Psxlatitem;
import com.auxgroup.hr.front.dozer.IObjectMapper;
import com.auxgroup.hr.front.service.comm.SysDictService;

/**
 * 奧克斯HR基础Controller
 * 
 * @author liuzhe
 *
 */
@SuppressWarnings("unchecked")
public abstract class BaseCO{
	
	/**
	 * 系统唯一标识（qr）
	 */
	@Value("${auxgroup.hr.systemcode}")
	protected String systemCode;
	
	@Resource(name = "dozerMapper")
	protected IObjectMapper objectMapper;
	
	@Autowired
	protected SysDictService sysDictService;
	
	protected Logger logger = LoggerFactory.getLogger(getClass());

	public BaseResponseVO buildRespone() {
		return new BaseResponseVO(BaseRetCode.CODE_SUCCESS);
	}
	public BaseResponseVO buildResponeData(String key, Object data) {
		HashMap<String, Object> hashMap = new HashMap<String, Object>();
		hashMap.put(key, data);
		return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, hashMap);
	}

	public BaseResponseVO buildRespone(Object data) {
		if (data != null) {
			if(isBaseType(data)){
				return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, data);
			}
			List<Map<String, Object>> datas = buildDictField(data);
			if(datas!=null&&datas.size()>1){
				return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, datas);
			}
			if(datas!=null&&datas.size()==1){
				return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, datas.get(0));
			}
			return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, data);
		} else {
			return new BaseResponseVO(BaseRetCode.CODE_SUCCESS);
		}
	}

	/**
	 * 原buildRespone构建返回值时，当list数据只有一条时，返回当条数据，现需返回一个列表，重新构建个方法，原流程不敢动
	 * @param data
	 * @return
	 */
	public BaseResponseVO buildResponeSpecial(Object data) {
		if (data != null) {
			if(isBaseType(data)){
				return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, data);
			}
			List<Map<String, Object>> datas = buildDictField(data);
			if(datas!=null&&datas.size()>0){
				return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, datas);
			}
//			if(datas!=null&&datas.size()==1){
//				return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, datas.get(0));
//			}
			return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, data);
		} else {
			return new BaseResponseVO(BaseRetCode.CODE_SUCCESS);
		}
	}
	
	/**
	 * 构建返回值
	 * @param data
	 * @param isDict 是否构建字典值字段
	 * @return
	 */
	public BaseResponseVO buildRespone(Object data,Boolean isDict) {
		if (data != null) {
			if(isDict){
				List<Map<String, Object>> datas = buildDictField(data);
				if(datas!=null&&datas.size()>1){
					return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, datas);
				}
				if(datas!=null&&datas.size()==1){
					return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, datas.get(0));
				}
			}
			return new BaseResponseVO(BaseRetCode.CODE_SUCCESS, data);
		} else {
			return new BaseResponseVO(BaseRetCode.CODE_SUCCESS);
		}
	}

	public BaseResponseVO buildRespone(BaseRetCode retCode) {
		return new BaseResponseVO(retCode);
	}
	public BaseResponseVO buildRespone(BaseRetCode retCode, Object data) {
		return new BaseResponseVO(retCode, buildDictField(data));
	}

	public BaseResponseVO buildRespone(String retCode, String retMsg) {
		return new BaseResponseVO(retCode, retMsg);
	}
	public BaseResponseVO buildRespone(FrontException e) {
		return new BaseResponseVO(e.getData().getErrorCode(), e.getData()
				.getErrorMsg(), e.getData().getErrorData());
	}
	public BaseResponseVO buildRespone(String retCode, String retMsg,
			Object data) {
		return new BaseResponseVO(retCode, retMsg, buildDictField(data));
	}

	/**
	 * 表单校验
	 * 
	 * @param binding
	 */
	public void assertValidation(BindingResult binding) {
		if (binding.hasErrors()) {
			List<FieldError> allErrors = binding.getFieldErrors();
			List<VailidationMsg> errors = new LinkedList<VailidationMsg>();
			for (FieldError objectError : allErrors) {
				errors.add(new VailidationMsg(objectError.getObjectName(),
						objectError.getDefaultMessage()));

			}
			throw new ValidationException(errors);
		}
	}

	public FrontException riseFrontException(Throwable e, BaseRetCode retCode) {
		return new FrontException(e, retCode);
	}

	public FrontException riseFrontException(BaseRetCode retCode) {
		return new FrontException(retCode);
	}
	/**
	 * 异常处理
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @param ex
	 * @return
	 */
	@ExceptionHandler
	@ResponseBody
	public BaseResponseVO resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		if (ex instanceof ValidationException) {
			logger.warn(getErrorMsg(ex, request), ex);
			ValidationException validationException = (ValidationException) ex;
			List<VailidationMsg> msgs = validationException.getErrors();
			String errorMsg = validationException.getData().getErrorMsg();
			if(msgs != null && !msgs.isEmpty()) {
				errorMsg = msgs.get(0).getMsg();
			}
			return buildRespone(validationException.getData().getErrorCode(), errorMsg);
		}
		if (ex instanceof FrontException) {
			logger.error(getErrorMsg(ex, request), ex);
			FrontException frontException = (FrontException) ex;
			return buildRespone(frontException.getData().getErrorCode(),
					frontException.getData().getErrorMsg());
		}
		if (ex instanceof UnauthorizedException) {
			logger.warn(getErrorMsg(ex, request), ex);
			response.setStatus(HttpServletResponse.SC_FORBIDDEN);
			return buildRespone(BaseRetCode.CODE_ERROR_AUTH_UNAUTH);
		}
		logger.error(getErrorMsg(ex, request), ex);
		return buildRespone(BaseRetCode.CODE_ERROR_SYS);
	}

	protected String getErrorMsg(Exception ex, HttpServletRequest request) {
		StringBuilder sb = new StringBuilder();
		sb.append("PathInfo is: ");
		sb.append(request.getPathInfo());
		sb.append(", EX msg is: ");
		sb.append(ex.getMessage());
		return sb.toString();
	}
	
	/**
	 * 单对象动态添加字典字段
	 * @param object 需要添加字典值的对象
	 * @return
	 */
	public Map<String, Object> buildDictFieldFromObject(Object object){
		Map<String, Object> objectMap = Bean2MapUtils.transBean2Map(object,true);
		return buildDictFieldFromObjectMap(objectMap);
	}
	
	/**
	 * 单对象动态添加字典字段
	 * @param object 需要添加字典值的对象
	 * @param isTrim 是否需要对对象中的string 进行trim操作
	 * @return
	 */
	public Map<String, Object> buildDictFieldFromObject(Object object,Boolean isTrim){
		Map<String, Object> objectMap = Bean2MapUtils.transBean2Map(object,isTrim);
		return buildDictFieldFromObjectMap(objectMap);
	}
	
	
	private Map<String, Object> buildDictFieldFromObjectMap(Map<String, Object> objectMap){
		Map<String, Object> newMap = new HashMap<String, Object>();
		Set<String> keys = objectMap.keySet();
		String dictValue = "";
		for (String key : keys) {
			if(key.equals("cSeqno") || key.equals("CSeqno")){
				objectMap.put(key, objectMap.get(key)+"");
				continue;
			}
			//添加普通字典
			if(Constant.DICT_FIELD_SET.contains(key)){
				dictValue = getDictValue(Underline2Camel.camel2Underline(key),String.valueOf(objectMap.get(key)));
				newMap.put(key+"Value", dictValue);
				continue;
        	}
			//添加特殊的单表字典
			if(Constant.SINGLE_TABLE_DICT_SET.contains(key)){
				dictValue = sysDictService.getSingleTableDict(key, String.valueOf(objectMap.get(key)));
				newMap.put(key+"Value", dictValue);
				continue;
			}
			
		}
		newMap.putAll(objectMap);
		return newMap;
	}
	
	
	
	
	/**
	 * 动态添加字典字段
	 * @param object 需要添加字典值的对象
	 * @return
	 */
	public List<Map<String, Object>> buildDictField(Object object){
		List<Map<String, Object>> newMaps= new ArrayList<Map<String, Object>>();
		if(object instanceof List){
			List<Object> objects = (List<Object>)object;
			if(objects!=null&&!objects.isEmpty()){
				for (Object one : objects) {
					newMaps.add(buildDictFieldFromObject(one));
				}
			}
		}else{
			newMaps.add(buildDictFieldFromObject(object));
		}
		return newMaps;
	}
	
	/**
	 * 获取字典值
	 * @param fieldName
	 * @param fileValue
	 * @return
	 */
	protected String getDictValue(String fieldName,String fileValue){
		if(StringUtils.isEmpty(fileValue)) {
			return null;
		}
		Psxlatitem item = sysDictService.getSysDict(fieldName, fileValue);
		if(item!=null){
			return item.getXlatshortname();
		}
		return null;
	}
	
	
	/**
	 * 判断是否为包装类
	 * @param object
	 * @return
	 */
	private Boolean isBaseType(Object object){
		if(object instanceof String){
			return true;
		}
		if(object instanceof Integer){
			return true;
		}
		if(object instanceof Float){
			return true;
		}
		if(object instanceof Double){
			return true;
		}
		if(object instanceof Long){
			return true;
		}
		if(object instanceof Boolean){
			return true;
		}
		if(object instanceof Character){
			return true;
		}
		if(object instanceof Byte){
			return true;
		}
		return false;
	}
}
